#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include "InetAddr.hpp"
#include "Thread.hpp"

using namespace wxd;

int sockfd = -1;
struct sockaddr_in peer;
pthread_t id;
void Send()
{
    while (true)
    {
        std::string send_message;
        // 从标准输出流中获取消息
        std::cout << "Please enter# ";
        std::getline(std::cin, send_message);
        // 发消息-发送即为登录成功
        int n = sendto(sockfd, send_message.c_str(), send_message.size(), 0, (sockaddr *)&peer, sizeof(peer));
        if(send_message == "QUIT")
        {
            pthread_cancel(id);
            break;
        }
    }
}

void Recive()
{
    while (true)
    {
        char message[1024];

        socklen_t peer_len = sizeof(peer);
        // 收消息
        int msg_len = recvfrom(sockfd, message, sizeof(message) - 1, 0, (sockaddr *)&peer, &peer_len);
        if (msg_len < 0)
        {
            std::cerr << "收消息出错！" << std::endl;
            return;
        }
        message[msg_len] = 0;
        // 打印收到的消息
        std::cerr << message << std::endl;
    }
}

int main(int argc, char *argv[])
{
    // 获取服务器的ip和端口
    if (argc != 3)
    {
        std::cerr << "usage: " << argv[0] << "server_ip server_port";
        return 1;
    }

    std::string server_ip = argv[1];
    u_int16_t server_port = std::stoi(argv[2]);

    InetAddrTrans addr_trans(server_ip, server_port);
    peer = addr_trans(); // 调用仿函数返回sockaddr_in

    // 创建套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
    {
        std::cerr << "创建Socket失败！" << std::endl;
        return 1;
    }

    using client_task_t = std::function<void()>;

    // 一个线程来进行收消息，一个线程来进行发消息
    Thread sender(Send);
    Thread recver(Recive);
    
    sender.start();
    recver.start();
    id = recver.Id();
    
    sender.join();
    recver.join();
    return 0;
}
